#!/usr/bin/env python2

import os
import sys
import time
import socket
import re
import string
import readline
import errno
from cluster import Cluster
from utils import Exp, _exec_pipe

from buddha.color_output import red, fuchsia

#from buddha.color_output import red, yellow, blue, \
#        green, purple, darkgreen, darkyellow, darkblue, \
#        turquoise, fuchsia


class LICHShell:
    def __init__(self):
        self.__reload()
        self.PROMPT = red('root') + fuchsia('@%s # ' % (self.cluster.config.clustername))

    def __reload(self):
        # print("reload env")
        self.cluster = Cluster()
        self.bin = os.path.join(self.cluster.config.lich + '/libexec')
        self.cmds = os.listdir(self.bin)
        self.cmds += ['cluster', 'storage', 'node', 'help', 'os']
        self.prefix = self.cluster.config.lich + '/bin/lich4.'

    def _completer(self, word, index):
        if '/' in word:
            matches = self._path_completer(word)
        else:
            matches = [c for c in self.cmds if c.startswith(word)]
        try:
            return matches[index] + ''
        except IndexError:
            pass

    def _path_completer(self, text):
        (head, tail) = os.path.split(text)
        matches = []
        if head and os.path.exists(head):
            if head == '/':
                matches = [head + f if os.path.isfile(os.path.join(head, f)) else head + f + os.sep for f in os.listdir(head) if f.startswith(tail)]
            else:
                matches = [head + os. sep + f if os.path.isfile(os.path.join(head, f)) else head + os.sep + f + os.sep for f in os.listdir(head) if f.startswith(tail)]
        return matches

    def start(self):
        readline.set_completer(self._completer)
        readline.set_completer_delims(''.join([c for c in readline.get_completer_delims() if c != '/' and c != '-']))
        readline.parse_and_bind("tab: complete")
        cmd = None

        self.__show_hosts()
        self.__show_help()

        while True:
            try:
                cmd = raw_input(self.PROMPT)
            except EOFError:
                print 'exit'
                exit(0)
            except KeyboardInterrupt:
                print 'type ctrl-D to exit lich shell'
                continue

            if cmd:
                self._parse_cmd(cmd)

    def _parse_cmd(self, cmd):
        if cmd.startswith('cluster') or \
                cmd.startswith('storage') or \
                cmd.startswith('help') or \
                cmd.startswith('os') or \
                cmd.startswith('node'):

            try:
                self.fetch_job(cmd)
            except Exp, e:
                if (e.errno == errno.EINVAL or e.errno == errno.EEXIST):
                    print (e.err)
                    pass;
                else:
                    print (e.err)
                    exit(e.errno)
        else:
            self._shell(cmd)

        self.__reload()

    def _shell(self, cmd):
        command = cmd.strip().split()[0]
        command = os.path.join(self.bin, command)

        if os.path.exists(command):
            os.system(os.path.join(self.bin, cmd))
        else:
            print 'lich-sh: %s: command not found' % cmd

    def __show_hosts(self):
        print (" list of node:")
        print (" =====================")
        for i in self.cluster.config.hosts.keys():
            print ("    *" + i)

        print ("     total : %u\n" % (len(self.cluster.config.hosts.keys())))

    def __show_help(self):
        help = " list of command:\n" \
               " =====================\n" \
               "     cluster --help\n"\
               "     storage --help\n"\
               "     node --help\n"\
               "     help\n"
        print help

    def fetch_job(self, cmd):
        cmd = cmd.strip().split(None, 2)

        service = None
        host = None
        if (cmd[0] == 'help'):
            self.__show_help()
        elif (cmd[0] == 'os'):
            self.cluster.os_cmd(cmd)
        elif (len(cmd) == 1 or cmd[1] == "--help"):
            print (self.prefix)
            res = _exec_pipe([self.prefix + cmd[0] , '--help'], 0, False)
            print(res.replace(self.prefix, ""))

        else:
            cmd1 = self.prefix + cmd[0]
            for i in cmd[1:]:
                cmd1 = cmd1 + ' ' + i
            os.system(cmd1)


if __name__ == '__main__':
    argc = len(sys.argv)

    if os.geteuid() != 0:
        print red('Need to be root :(')
        exit(1)

    if argc == 1:
        test = LICHShell()
        test.start()
    else:
        print 'invalid option'
